package com.zgkxzx.myfix;

import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 创建者 zgkxzx
 * 日期   1/30/18
 * 描述
 */

public class HandleNative {


    private static final String TAG = HandleNative.class.getSimpleName();

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    /**
     * 初始化方法
     * @param appVersion
     */
    public static native int init(int appVersion);

    /**
     * 方法的替换
     * @param src
     * @param dest
     */
    public static native void replaceMethod(Method src,Method dest);


    public static native void setFieldFlag(Field field);


    /**
     * initialize the target class, and modify access flag of class’ fields to
     * public
     *
     * @param clazz
     *            target class
     * @return initialized class
     */
    public static Class<?> initTargetClass(Class<?> clazz) {
        try {
            Class<?> targetClazz = Class.forName(clazz.getName(), true,
                    clazz.getClassLoader());

            initFields(targetClazz);
            return targetClazz;
        } catch (Exception e) {
            Log.e(TAG, "initTargetClass", e);
        }
        return null;
    }

    /**
     * modify access flag of class’ fields to public
     *
     * @param clazz
     *            class
     */
    private static void initFields(Class<?> clazz) {
        Field[] srcFields = clazz.getDeclaredFields();
        for (Field srcField : srcFields) {
            Log.d(TAG, "modify " + clazz.getName() + "." + srcField.getName()
                    + " flag:");
            setFieldFlag(srcField);
        }
    }

    /**
     * replace method's body
     *
     * @param src
     *            source method
     * @param dest
     *            target method
     *
     */
    public static void addReplaceMethod(Method src, Method dest) {
        try {
            replaceMethod(src, dest);
            initFields(dest.getDeclaringClass());
        } catch (Throwable e) {
            Log.e(TAG, "addReplaceMethod", e);
        }
    }




}
